package com.java.spring.simple.module.admin.auth.service;

import org.springframework.stereotype.Service;

import com.java.spring.simple.common.core.constant.Constants;
import com.java.spring.simple.common.core.domain.model.LoginUser;
import com.java.spring.simple.common.core.enums.DeviceType;
import com.java.spring.simple.common.core.enums.LoginType;
import com.java.spring.simple.common.core.utils.MessageUtils;
import com.java.spring.simple.common.satoken.utils.LoginHelper;
import com.java.spring.simple.common.tenant.helper.TenantHelper;
import com.java.spring.simple.module.admin.auth.service.executor.AuthLoginExecutor;
import com.java.spring.simple.module.infrastructure.domin.vo.SysUserVo;

import cn.dev33.satoken.exception.NotLoginException;
import cn.dev33.satoken.secure.BCrypt;
import cn.dev33.satoken.stp.StpUtil;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;

/**
 * 登录校验方法
 *
 * @author Lion Li
 */
@Slf4j
@Service
public class AuthLoginService {

    @Resource
    private AuthLoginExecutor authLoginExecutor;

    /**
     * 登录验证
     *
     * @param username 用户名
     * @param password 密码
     * @param code 验证码
     * @param uuid 唯一标识
     * @return 结果
     */
    public String login(String tenantId, String username, String password, String code, String uuid) {
        SysUserVo user = authLoginExecutor.loadUserByUsername(tenantId, username);
        authLoginExecutor.checkLogin(LoginType.PASSWORD, tenantId, username,
            () -> !BCrypt.checkpw(password, user.getPassword()));
        // 此处可根据登录用户的数据不同 自行创建 loginUser
        LoginUser loginUser = authLoginExecutor.buildLoginUser(user);
        // 执行登录
        LoginHelper.loginByDevice(loginUser, DeviceType.PC);

        authLoginExecutor.recordLogininfor(loginUser.getTenantId(), username, Constants.LOGIN_SUCCESS,
            MessageUtils.message("user.login.success"));
        authLoginExecutor.recordLoginInfo(user.getUserId());
        return StpUtil.getTokenValue();
    }

    /**
     * 登录验证
     *
     * @param tenantId 租户ID
     * @param phonenumber 手机号码
     * @param smsCode 短信验证码
     * @return 结果
     */
    public String smsLogin(String tenantId, String phonenumber, String smsCode) {
        // 校验租户
        authLoginExecutor.checkTenant(tenantId);
        // 通过手机号查找用户
        SysUserVo user = authLoginExecutor.loadUserByPhonenumber(tenantId, phonenumber);

        authLoginExecutor.checkLogin(LoginType.SMS, tenantId, user.getUserName(),
            () -> !authLoginExecutor.validateSmsCode(tenantId, phonenumber, smsCode));
        // 此处可根据登录用户的数据不同 自行创建 loginUser
        LoginUser loginUser = authLoginExecutor.buildLoginUser(user);
        // 生成token
        LoginHelper.loginByDevice(loginUser, DeviceType.APP);

        authLoginExecutor.recordLogininfor(loginUser.getTenantId(), user.getUserName(), Constants.LOGIN_SUCCESS,
            MessageUtils.message("user.login.success"));
        authLoginExecutor.recordLoginInfo(user.getUserId());
        return StpUtil.getTokenValue();
    }

    /**
     * 退出登录
     */
    public void logout() {
        try {
            LoginUser loginUser = LoginHelper.getLoginUser();
            if (TenantHelper.isEnable() && LoginHelper.isSuperAdmin()) {
                // 超级管理员 登出清除动态租户
                TenantHelper.clearDynamic();
            }
            StpUtil.logout();
            authLoginExecutor.recordLogininfor(loginUser.getTenantId(), loginUser.getUsername(), Constants.LOGOUT,
                MessageUtils.message("user.logout.success"));
        } catch (NotLoginException ignored) {
        }
    }

}
